package com.sk.bilibili.service;

import com.sk.bilibili.property.MinioProperty;
import com.sk.bilibili.utils.NameCreator;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.Result;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 邵康
 * @date 2021/11/16 13:32
 */
@Service
public class MinioService implements InitializingBean {

    @Autowired
    private MinioProperty minioProperty;
    private MinioClient minioClient;

    @Override
    public void afterPropertiesSet() throws Exception {
        minioClient=new MinioClient(minioProperty.getEndPoint(), minioProperty.getAccessKey(),
                minioProperty.getSecretKey());
    }

    public String add(MultipartFile file, String path) {
        if(file==null)return null;
        String key = String.format(path, NameCreator.getName());
        uploadStream(file,key);
        return minioProperty.getBasePath()+key;
    }

    @SneakyThrows
    public String uploadStream(File file, String path){
        FileInputStream is = new FileInputStream(file);
        return uploadStream(is, path);
    }

    @SneakyThrows
    public void uploadStream(MultipartFile file, String key) {
        PutObjectOptions options = new PutObjectOptions(file.getSize(), -1);
        options.setContentType(file.getContentType());
        InputStream is = file.getInputStream();
        minioClient.putObject(minioProperty.getBucketName(),key, is,options);
        is.close();
    }

    @SneakyThrows
    public String copy(String srcKey, String tarKey){
        String bucketName = minioProperty.getBucketName();
        minioClient.copyObject(bucketName,tarKey,null,null,
                bucketName,srcKey,null,null);
        return minioProperty.getBasePath()+tarKey;
    }

    public void delete(String path, Pattern pattern) {
        Matcher matcher = pattern.matcher(path);//默认值的存在  一定有值  只要判断是否为默认值就可以了
        if(matcher.find())deleteFile(matcher.group(1));
    }

    @SneakyThrows
    public void deleteFile(String key) {
        minioClient.removeObject(minioProperty.getBucketName(),key);
    }

    public String update(String path, Pattern pattern, String cover, MultipartFile file) {
        if(file==null)return null;
        Matcher matcher = pattern.matcher(cover);
        if(matcher.find()){//路径不可能为空  判断是否为对应的格式  若是就覆盖 否则 添加
            uploadStream(file,matcher.group(1));
            return cover;
        }else {
            return add(file,path);
        }
    }

    @SneakyThrows
    public List<String> list(String baseKey){
        Iterable<Result<Item>> results = minioClient.listObjects(minioProperty.getBucketName(), baseKey);
        List<String> res=new ArrayList<>();
        for (Result<Item> result:results){
            Item item = result.get();
            res.add(minioProperty.getBasePath()+item.objectName());
        }
        return res;
    }

    @SneakyThrows
    public String uploadStream(InputStream is, String path) {
        return uploadStream(is,is.available(),path);
    }

    @SneakyThrows
    public String uploadStream(InputStream is, int size, String path) {
        String key = String.format(path, NameCreator.getName());
        PutObjectOptions options = new PutObjectOptions(size, -1);
        minioClient.putObject(minioProperty.getBucketName(),key,is,options);
        is.close();
        return minioProperty.getBasePath()+key;
    }

    // DEBUG  使用
    public MinioClient getMinioClient() {
        return minioClient;
    }

}
